// SPDX-License-Identifier: Mulan PSL v2
/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This software is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use thiserror::Error;
use crate::mock_common::ipc::{
    framer::GenericFramerError,
    transport::shmem::ShmemTransportError,
};

/// Comprehensive error type for the xgpu-server.
#[derive(Error, Debug)]
pub enum ServerError {
    /// Transport layer errors.
    #[error("Transport error: {0}")]
    Transport(#[from] ShmemTransportError),

    /// Framing layer errors.
    #[error("Framer error: {0}")]
    Framer(#[from] GenericFramerError),

    /// CUDA runtime errors.
    #[error("CUDA error: {message} (code: {code})")]
    Cuda { message: String, code: i32 },

    /// GPU resource management errors.
    #[error("Resource error: {0}")]
    Resource(String),

    /// Request processing errors.
    #[error("Request processing error: {0}")]
    RequestProcessing(String),

    /// Configuration errors.
    #[error("Configuration error: {0}")]
    Configuration(String),

    /// Server lifecycle errors.
    #[error("Server lifecycle error: {0}")]
    Lifecycle(String),

    /// I/O errors.
    #[error("I/O error: {0}")]
    Io(#[from] std::io::Error),

    /// Serialization/deserialization errors.
    #[error("Serialization error: {0}")]
    Serialization(#[from] serde_json::Error),

    /// Generic errors.
    #[error("Internal error: {0}")]
    Internal(String),
}

/// Result type alias for server operations.
pub type ServerResult<T> = Result<T, ServerError>;

impl ServerError {
    /// Create a new CUDA error.
    pub fn cuda(message: impl Into<String>, code: i32) -> Self {
        Self::Cuda {
            message: message.into(),
            code,
        }
    }

    /// Create a new resource error.
    pub fn resource(message: impl Into<String>) -> Self {
        Self::Resource(message.into())
    }

    /// Create a new request processing error.
    pub fn request_processing(message: impl Into<String>) -> Self {
        Self::RequestProcessing(message.into())
    }

    /// Create a new configuration error.
    pub fn configuration(message: impl Into<String>) -> Self {
        Self::Configuration(message.into())
    }

    /// Create a new lifecycle error.
    pub fn lifecycle(message: impl Into<String>) -> Self {
        Self::Lifecycle(message.into())
    }

    /// Create a new transport error.
    pub fn transport(error: ShmemTransportError) -> Self {
        Self::Transport(error)
    }

    /// Create a new internal error.
    pub fn internal(message: impl Into<String>) -> Self {
        Self::Internal(message.into())
    }
}